package model.entity.brain;

import java.util.Random;

import model.Executable;
import model.GameClock;
import model.entity.Avatar;
import model.entity.BasicEntity;
import model.handler.MovementHandler;
import model.map.Direction;
import model.map.HexLocationProjection;
import model.map.Location;
import model.map.World;
import utilities.*;

public class WanderingBrain extends Brain implements Archiveable {
	private Location avatarLoc;
	private BasicEntity npc;
	private Executable ex;
	
	public WanderingBrain(Avatar av, BasicEntity ent){
		//avatarLoc = av.getLocation();
		avatarLoc = World.getInstance().getPlayer().getLocation();
		npc = ent;
		
		GameClock.getInstance().schedule(40, new Executable() {
			public void execute() { start(); }
		});
		
	}
	
	public WanderingBrain() {
		// TODO Auto-generated constructor stub
	}

	public void start(){
		MovementHandler mh = MovementHandler.getInstance();
		mh.moveEntity(npc, getNextMove());
		
		final GameClock c = GameClock.getInstance();
		
		this.ex = new Executable() {
			public void execute() {
				MovementHandler mh = MovementHandler.getInstance();
				mh.moveEntity(npc, getNextMove());
			}
		};
		
		c.scheduleAtFixedRate( 10, this.ex );
	}
	
	public void cancelBrainFunctioning() {
		GameClock.getInstance().remove( this.ex );
	}
	
	/**
	 * move the npc in a random direction
	 * @return
	 */
	private Direction getNextMove(){
		Direction dir = Direction.SW;
		HexLocationProjection hlp = new HexLocationProjection();
		
		Random randGen = new Random();
		int numPadDirection = 5;
		// keep randomly choosing numbers until it is 1,2,3 or 7,8,9 for movingdirections (related to keypad)
		while(numPadDirection == 4 || numPadDirection == 5 || numPadDirection == 6){
			numPadDirection = randGen.nextInt(10);
			
			// convert the number chosen to a direction
			switch(numPadDirection){
				case 1: dir = Direction.SW; break;
				case 2: dir = Direction.S; break;
				case 3: dir = Direction.SE; break;
				case 7: dir = Direction.NW; break;
				case 8: dir = Direction.N; break;
				case 9: dir = Direction.NE; break;
			}
			
			// if we would move into the avatar, recalculate
			if (hlp.projectLocation(npc.getLocation(), dir) == avatarLoc){
				numPadDirection = 5;
			}
		}
		
		return dir;
	}
	
	public Archive save() {
		Archive archive = super.save();
		
//		archive.putClassName("avatarLoc", this.avatarLoc.getClass().getName());
//		archive.putOneRelationship("avatarLoc", this.avatarLoc);
		
		return archive;
	}
	
	public void load(Archive archive) {
		super.load(archive);
		
//		this.avatarLoc = (Location)ModelFactory.getInstance().createInstanceWithClassName("avatarLoc");
//		this.avatarLoc.load(archive.getOneRelationship("avatarLoc"));
	}
}